변경이 일어날 때마다 호출되는 멤버함수(콜백함수)를 베이스 클래스에 정의해 둔다.
클라이언트에서 해당 베이스를 상속받아 변경 시점에 수행할 작업을 구현한다.
struct PersonListener{
virtual void person_changed(Person& p, const string& property_name, const std::any new_value)=0;
};
위와 같이 정의하면, Person에서만 사용 가능한 관찰자이다.
템플릿(제네릭 프로그래밍)을 이용해서 다양한 타입에 대한 Observer를 정의
template <typename T> struct Observer{
virtual void field_changed(T& source, const string& field_name)=0;
};
Person 클래스의 변경 사항을 모니터링하기 위해 Observer<Person> 상속
struct ConsolePersonObserver: Observer<Person>{
void field_changed(Person& source, const string& field_name) override {
cout<<"Person's "<<field_name<<" has changed to "<<source.get_age()".\n";
}
};
struct ConsolePersonObserver: Observer<Person>, Observer<Creature>{
}
혹은 <any>의 std::any를 이용하여 제네릭으로 구현할 수 있다.